<?php
/**
 * clase_zen_POA_XML.php
 * @author Juan Belon
 * @access public
 * @copyright LGPL, GPL
 * @package zen_POA
 * @version 0.1.1
 * @uses zenphp FrameWork
 * @link http://csl2-zenphp.forja.rediris.es
 * @link http://www.zenphp.es
 * @link https://forja.rediris.es/projects/csl2-zenphp/
 * @magic Generador de un árbol XML
 * TODO: Completar la Documentación de las clases de POA
 */
// +----------------------------------------------------------------------
// | zenphp.es
// +----------------------------------------------------------------------
require_once "clase_zen_POA_ElementoXML.php";


class zen_POA_XML
{
	var $_analizador;
	var $actual;
	var $elemento_doc;


	function zen_POA_XML()
	{
		$this->actual = null;

		$this->_analizador = xml_parser_create();

        xml_set_object($this->_analizador, $this);
        xml_parser_set_option($this->_analizador, XML_OPTION_CASE_FOLDING, 0);

        xml_set_element_handler($this->_analizador, "_inicioElemento", "_finElemento");
        xml_set_character_data_handler($this->_analizador, "_CdatosElemento");
	}


	function &construirDesdeCadena($cadena_xml)
	{
		$xmlReader = new zen_POA_XML();

		return $xmlReader->_analizar($cadena_xml);
	}


	function &_analizar($datos)
    {
        
		if (!xml_parse($this->_analizador, $datos)) {
			$mensaje = xml_error_string(xml_get_error_code($this->_analizador));
			$linea = xml_get_current_line_number($this->_analizador);

			xml_parser_free($this->_analizador);

			die(sprintf(_("zen_POA_XML error: %s en la linea %d"), $mensaje, $linea));
		}
        
		xml_parser_free($this->_analizador);
        
		return $this->elemento_doc;
	}


	function _inicioElemento($analizador, $nombreEtiq, $atributos)
	{
		if (strtolower($nombreEtiq) == "punto_corte") {
			if (array_key_exists("nombre", $atributos) && array_key_exists("auto", $atributos)) {
				trigger_error(
					_("<b>[Error de Aspecto]:</b> El Nodo de Punto de corte'") . $contenido[0/*sizeof($index)-1*/]->obtenerAtributo("nombre") . 
                                        _("' no puede tener un 'nombre' y al mismo tiempo definir 'auto'!"),
					E_USER_ERROR
				);
			} elseif (!array_key_exists("nombre", $atributos) && !array_key_exists("auto", $atributos)) {
				trigger_error(
					_("<b>[Error de Aspecto]:</b> El Nodo de Punto de corte no tiene un atributo 'nombre' o 'auto' definido!"),
					E_USER_ERROR
				);
			}
		}

		$el =& new zen_POA_ElementoXML($nombreEtiq);
		$el->ponerAtributos($atributos);
		$el->ponerPadre($this->actual);

		if ($this->actual !== null) {
			$this->actual->insertarHijo($el);
		} else {
			$this->elemento_doc = & $el;
		}

		$this->actual = & $el;
	}


	function _finElemento($analizador, $nombreEtiq)
	{
		if ($this->actual !== null) {
			if ($this->actual->obtenerEtiqueta() != $nombreEtiq) {
				trigger_error(sprintf(
                                              _("<b>zen_POA_XML:[Error de Aspecto]:</b> El Nodo XML '%s no corresponde a la herecia correcta!"),$nombreEtiq),
					E_USER_ERROR
				);
			}

			$this->actual = & $this->actual->obtenerPadre();
		}
	}


	function _CdatosElemento($analizador, $datos)
	{
		if (strlen(trim($datos)) > 0) {
			$cdatos = & new zen_POA_ElementoXML("#text");
			$cdatos->ponerValor($datos);
			$cdatos->ponerPadre($this->actual);

			$this->actual->insertarHijo($cdatos);
	    }
	}
}

?>